package com.chain.BrotherExchange.ui.activity;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.util.Pair;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatImageView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.chain.BrotherExchange.C;
import com.chain.BrotherExchange.R;
import com.chain.BrotherExchange.data.Resource;
import com.chain.BrotherExchange.event.UserAssetsChangeEvent;
import com.chain.BrotherExchange.ui.adapter.TextWatcherAdapter;
import com.chain.BrotherExchange.ui.core.BaseActivity;
import com.chain.BrotherExchange.ui.dialog.VerifyCodeAndTransactionDialog;
import com.chain.BrotherExchange.ui.listener.TransactionPasswordIntercept;
import com.chain.BrotherExchange.utils.ActivityBarHelper;
import com.chain.BrotherExchange.utils.Androids;
import com.chain.BrotherExchange.utils.TimeCount;
import com.chain.BrotherExchange.utils.ViewUtils;
import com.chain.BrotherExchange.viewmodel.ExtractMoneyViewModel;
import com.chain.BrotherExchange.viewmodel.core.ViewModelProviders;
import com.example.common.zxing.ui.CaptureActivity;

import org.greenrobot.eventbus.EventBus;

import java.text.DecimalFormat;
import java.util.List;
import java.util.Objects;

import butterknife.Bind;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

import static com.chain.BrotherExchange.viewmodel.VerificationManage.verifyAddress;
import static com.chain.BrotherExchange.viewmodel.VerificationManage.verifyExtractCoinNumber;
import static com.example.common.zxing.ui.CaptureActivity.INTENT_EXTRA_KEY_QR_SCAN;

/**
 * 提币
 */
public class ExtractionMonetaryActivity extends BaseActivity implements EasyPermissions.PermissionCallbacks {

    @Bind(R.id.gas_text) TextView mGasText;
    @Bind(R.id.unit_number) TextView mUnitNumber;
    @Bind(R.id.apply_button) Button mApplyButton;
    @Bind(R.id.all_text_view) TextView mAllTextView;
    @Bind(R.id.get_number) EditText mNumberEditText;
    @Bind(R.id.coin_type_text) TextView mCoinTypeText;
    @Bind(R.id.balance_text_view) TextView mBalanceTextView;
    @Bind(R.id.address_edit_text) EditText mAddressEditText;
    @Bind(R.id.account_number_text_view) TextView mAccountNumberTextView;
    @Bind(R.id.add_address_rq_image) AppCompatImageView mAddAddressRqImage;
    @Bind(R.id.add_mention_address_layout) LinearLayout mAddMentionAddressLayout;

    private ExtractMoneyViewModel mViewModel;

    public static void launch(TextView balanceView, TextView typeView, String coinId) {
        Activity activity = (Activity) balanceView.getContext();
        Pair balancePair = new Pair<>(balanceView, ViewCompat.getTransitionName(balanceView));
        Pair typePair = new Pair<>(typeView, ViewCompat.getTransitionName(typeView));
        ActivityCompat.startActivity(activity,
                new Intent(activity, ExtractionMonetaryActivity.class)
                        .putExtra(C.EXTRA_BALANCE, balanceView.getText().toString())
                        .putExtra(C.EXTRA_COIN_TYPE, typeView.getText().toString())
                        .putExtra(C.EXTRA_COIN_ID, coinId),
                ActivityOptionsCompat.makeSceneTransitionAnimation(activity, balancePair, typePair).toBundle());
    }

    @Override
    protected int getLayoutID() {
        return R.layout.activity_extraction_monetary;
    }

    @Override
    protected void initActions() {
        ActivityBarHelper.init(this, R.string.title_extraction_monetary);

        // 网络及逻辑操作
        mViewModel = ViewModelProviders.of(this).get(ExtractMoneyViewModel.class);

        // 货币类型及余额
        mBalanceTextView.setText(getIntent().getStringExtra(C.EXTRA_BALANCE));
        mCoinTypeText.setText(getIntent().getStringExtra(C.EXTRA_COIN_TYPE));

        // 提币
        mApplyButton.setOnClickListener(new TransactionPasswordIntercept(
                v -> startExtractMoney())
        );

        // 扫描二维码
        mAddAddressRqImage.setOnClickListener(v -> requestPermission());

        // 提币全部货币
        mAllTextView.setOnClickListener(v ->
                ViewUtils.setTextAndSelectionEnd(mBalanceTextView, mNumberEditText)
        );

        // 选择提币地址
        ViewUtils.notEditable(mAddressEditText);
        mAddressEditText.setOnClickListener(v ->
                ExtractAddressManageActivity.launch(this, C.VALUE_GET_ADDRESS));

        // 手续费
        initExtractMoneyProcedureFee();

        // 到账数量
        initAccountNumber();
    }

    private void startExtractMoney() {
        String address = mAddressEditText.getText().toString();
        String number = mNumberEditText.getText().toString();
        if (verifyAddress(address) && verifyExtractCoinNumber(number)) {
            VerifyCodeAndTransactionDialog.show(this,
                    v -> sendMessage((TextView) v),
                    this::extractMoney
            );
        }
    }

    private void sendMessage(TextView textView) {
        mViewModel.sendMessage().observe(this, resource -> {
            if (resource.state == Resource.Status.LOADING) {
                textView.setClickable(false);
                textView.setBackgroundColor(Color.parseColor("#CCCCCC"));
                textView.setText(R.string.message_sending);
            } else {
                Androids.makeText(resource.message);
                if (resource.state == Resource.Status.SUCCESS) {
                    new TimeCount(textView).start();
                }
            }
        });
    }

    private void extractMoney(VerifyCodeAndTransactionDialog dialog) {
        String code = dialog.getCode();
        String password = dialog.getPassword();
        String address = mAddressEditText.getText().toString();
        String number = mNumberEditText.getText().toString(); // 提币数量
        String accountNumber = mAccountNumberTextView.getText().toString(); // 到账数量
        String gas = mGasText.getText().toString();

        String coinId = getIntent().getStringExtra(C.EXTRA_COIN_ID);
        mViewModel.extractMoney(coinId, address, number, accountNumber, gas, code, password)
                .observe(this, resource ->
                        Resource.load(this, resource, dialog, result -> {
                            dialog.successNetwork();
                            Androids.makeText(result.getMsg());
                            EventBus.getDefault().post(new UserAssetsChangeEvent());
                            finish();
                        })
                );
    }

    private void initAccountNumber() {
        mNumberEditText.addTextChangedListener(new TextWatcherAdapter(s ->
                mViewModel.accountNumber(s.toString()).observe(this, number ->
                        mAccountNumberTextView.setText(number)
                )
        ));
    }

    private void initExtractMoneyProcedureFee() {
        mViewModel.procedureFee().observe(this, resource -> {
            switch (resource.state) {
                case ERROR:
                    initProcedureFeeError();
                    break;
                case SUCCESS:
                    initProcedureFeeView(resource.source);
                    break;
            }
        });
    }

    private void initProcedureFeeView(double poundage){
        DecimalFormat df = new DecimalFormat("#########.########");
        mGasText.setText(df.format(poundage));

        mNumberEditText.addTextChangedListener(new TextWatcherAdapter(s -> {
            if (s.length() > 0) {
                double numberDouble = Double.parseDouble(s.toString());

                // 到账数量
                double receiveNumber = numberDouble - (poundage * numberDouble);
                mAccountNumberTextView.setText(df.format(receiveNumber));

                // 手续费
                mGasText.setText(df.format(numberDouble - receiveNumber));
            } else {
                mAccountNumberTextView.setText("0");
            }
        }));
    }

    private void initProcedureFeeError() {
        AlertDialog alertDialog = new AlertDialog.Builder(this)
                .setTitle(R.string.get_procedure_fee_error)
                .setMessage(R.string.message_exit_retry)
                .setPositiveButton(R.string.sure, (dialog, which) -> finish())
                .create();
        alertDialog.setCancelable(false);
        alertDialog.show();
    }

    private void requestPermission() {
        String[] permissions = new String[]{Manifest.permission.CAMERA};
        if (!EasyPermissions.hasPermissions(this, permissions)) {
            String rationale = getString(R.string.please_approve_camera_permissions);
            EasyPermissions.requestPermissions(this, rationale, 0, permissions);
        } else {
            CaptureActivity.launch(this);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
            CaptureActivity.launch(this);
        } else if (resultCode == RESULT_OK && requestCode == C.REQ_COIN_ADDRESS) {
            String address = data.getStringExtra(C.EXTRA_COIN_ADDRESS);
            mAddressEditText.setText(address);
        } else if (resultCode == 0xA1 && data != null) {
            Bundle bundle = data.getExtras();
            String scanResult = Objects.requireNonNull(bundle).getString(INTENT_EXTRA_KEY_QR_SCAN);
            mAddressEditText.setText(scanResult);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        CaptureActivity.launch(this);
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this).setTitle(R.string.auto_authorization_failure)
                    .setRationale(R.string.please_manually_select_approve_camera_permissions).build().show();
        } else {
            Androids.makeText(R.string.authorization_failure);
        }
    }
}
